home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #11 / Amiga Plus CD - 2002 - No. 11.iso / Tools / Freeware / sysmon / src / sysinfo / mylibinit.c next >
C/C++ Source or Header  |  2002-10-27  |  10KB  |  320 lines

  1. /* Slightly modified version of SAS/C libinit.c to handle delayed expunges **
  2. ** __UserLibCleanup will return a non-zero value if the expunge needs to   **
  3. ** be delayed                                   */
  4.  
  5. #define  _USEOLDEXEC_ 1
  6. #include <exec/types.h>
  7. #include <exec/nodes.h>
  8. #include <exec/memory.h>
  9. #include <exec/resident.h>
  10. #include <exec/libraries.h>
  11. #include <exec/execbase.h>
  12. #include <libraries/dos.h>
  13. #include <proto/exec.h>
  14. #include <proto/dos.h>
  15. #include <string.h>
  16.  
  17. long _WBenchMsg;
  18.  
  19. /* Prototypes */
  20. ULONG __asm _LibExpunge( register __a6 struct MyLibrary *libbase );
  21. ULONG __asm _LibInit   ( register __a0 APTR seglist,
  22.                          register __d0 struct MyLibrary *libbase );
  23.  
  24. int  __saveds __asm __UserLibInit   (register __a6 struct MyLibrary *libbase);
  25. int  __saveds __asm __UserLibCleanup(register __a6 struct MyLibrary *libbase);
  26.  
  27. int  __saveds __asm __UserDevInit   (register __d0 long unit,
  28.                                      register __a0 struct IORequest *ior,
  29.                                      register __a6 struct MyLibrary *libbase);
  30. int  __saveds __asm __UserDevCleanup(register __a0 struct IORequest *ior,
  31.                                      register __a6 struct MyLibrary *libbase);
  32.  
  33. int  __saveds __asm __libfpinit     (register __a6 struct MyLibrary *libbase);
  34. void __saveds __asm __libfpterm     (register __a6 struct MyLibrary *libbase);
  35.  
  36. struct MyLibrary {
  37.         struct             Library ml_Lib;
  38.         ULONG              ml_SegList;
  39.         ULONG              ml_Flags;
  40.         APTR               ml_ExecBase; /* pointer to exec base  */
  41. #ifndef ONE_GLOBAL_SECTION
  42.         long *             ml_relocs;   /* pointer to relocs.    */
  43.         struct MyLibrary * ml_origbase; /* pointer to original library base  */
  44.         long               ml_numjmps;
  45. #endif
  46. };
  47.  
  48. typedef LONG (*myPFL)();   /* pointer to function returning 32-bit int      */
  49.  
  50. /* library initialization table, used for AUTOINIT libraries                */
  51. struct InitTable {
  52.         ULONG        *it_DataSize;       /* library data space size         */
  53.         myPFL        *it_FuncTable;      /* table of entry points           */
  54.         APTR         it_DataInit;        /* table of data initializers      */
  55.         myPFL        it_InitFunc;        /* initialization function to run  */
  56. };
  57.  
  58. #ifndef ONE_GLOBAL_SECTION
  59. long _WBenchMsg;
  60. long _OSERR;
  61. long __base;
  62. #endif
  63.  
  64. /* symbols generated by blink */
  65. extern char __far _LibID[];             /* ID string                        */
  66. extern char __far _LibName[];           /* Name string                      */
  67. extern char __far RESLEN;               /* size of init data                */
  68. extern long __far NEWDATAL;             /* size of global data              */
  69. extern long __far NUMJMPS;              /* number of jmp vectors to copy    */
  70. extern myPFL _LibFuncTab[];             /* my function table                */
  71. extern long __far _LibVersion;          /* Version of library               */
  72. extern long __far _LibRevision;         /* Revision of library              */
  73. #define MYVERSION ((long)&_LibVersion)
  74. #define MYREVISION ((long)&_LibRevision)
  75. #define DATAWORDS ((long)&NEWDATAL)     /* magic to get right tpye of reloc */ 
  76. #define SIZEJMPTAB ((long)libbase->ml_origbase->ml_numjmps)
  77.                                         /* size in bytes of jmp table       */
  78.  
  79. /* From libent.o, needed to determine where data is loaded by loadseg       */
  80. extern long far _Libmergeddata; 
  81.  
  82. #define MYLIBRARYSIZE ((sizeof(struct MyLibrary) +3) & ~3)
  83.  
  84.  
  85.  
  86. struct InitTable __far _LibInitTab =  {
  87.         (long *)(&RESLEN+MYLIBRARYSIZE),
  88.         _LibFuncTab,
  89.         NULL,                        /* will initialize my own data */
  90.         _LibInit,
  91. };
  92.  
  93. __asm ULONG _LibInit( register __a0 APTR seglist,
  94.                       register __d0 struct MyLibrary *libbase )
  95. {
  96. #ifdef ONE_GLOBAL_SECTION
  97.     long *reloc;
  98. #endif
  99.     long *sdata;
  100.     char *ddata;
  101.     long nrelocs;
  102.  
  103.       
  104.     libbase->ml_SegList = (ULONG) seglist;
  105.  
  106.     /* init. library structure (since I don't do automatic data init.) */
  107. #ifdef DEVICE
  108.     libbase->ml_Lib.lib_Node.ln_Type = NT_DEVICE;
  109. #else
  110.     libbase->ml_Lib.lib_Node.ln_Type = NT_LIBRARY;
  111. #endif
  112.     libbase->ml_Lib.lib_Node.ln_Name =  _LibName;
  113.     libbase->ml_Lib.lib_Flags = LIBF_SUMUSED | LIBF_CHANGED;
  114.     libbase->ml_Lib.lib_Version = MYVERSION;
  115.     libbase->ml_Lib.lib_Revision = MYREVISION;
  116.     libbase->ml_Lib.lib_IdString = (APTR) _LibID;
  117. #ifndef ONE_GLOBAL_SECTION
  118.     libbase->ml_relocs = NULL;
  119.     libbase->ml_origbase = libbase;
  120.     sdata = (long *)_LibInitTab.it_FuncTable;
  121.     libbase->ml_numjmps = (long)&NUMJMPS;
  122. #endif
  123.  
  124.      /* Start of copy of global data after structure */
  125.     ddata = (char *)libbase + MYLIBRARYSIZE; 
  126.  
  127.     sdata = (long *)&_Libmergeddata; /* where loadseg loaded the data */
  128.     memcpy(ddata, (void *)sdata, DATAWORDS*4);
  129.  
  130.     /* perform relocs if we want one global section for all programs */
  131.     /* that have this lib open. If we want a global section for each */
  132.     /* open, copy the relocs, and do them on each open call.         */
  133.     sdata = sdata + DATAWORDS;
  134.     nrelocs = *sdata;
  135. #ifdef ONE_GLOBAL_SECTION
  136.     sdata++;
  137.     while (nrelocs > 0)
  138.     {
  139.        reloc = (long *)((long)ddata + *sdata++);
  140.        *reloc += (long)ddata;
  141.        nrelocs--;
  142.     }
  143.     
  144. #ifndef DEVICE
  145.     if (__UserLibInit(libbase) != 0)
  146.        return NULL; /* abort if user init failed */
  147. #endif
  148.  
  149. #else
  150.     if (nrelocs) 
  151.     {
  152.       if ((libbase->ml_relocs = AllocMem((nrelocs * 4) + 4, MEMF_PUBLIC)) == NULL)
  153.         return 0;
  154.       memcpy((void *)libbase->ml_relocs, (void *)sdata, (nrelocs * 4) + 4);
  155.     }
  156. #endif
  157.  
  158.     return ( (ULONG) libbase );
  159. }
  160.  
  161. LONG __asm _LibOpen( 
  162. #ifdef DEVICE
  163.                      register __d0 long unit,
  164.                      register __a1 struct IORequest *ior,
  165. #endif
  166.                      register __a6 struct MyLibrary *libbase )
  167. {
  168. #ifndef ONE_GLOBAL_SECTION
  169.     struct MyLibrary *origbase = libbase;
  170.     struct ExecBase *SysBase = *(struct ExecBase **)4;
  171.     char *newlib;
  172.     long *sdata, *ddata, *reloc;
  173.     long nrelocs;
  174. #endif
  175.  
  176.     /* mark us as having another customer */
  177.     libbase->ml_Lib.lib_OpenCnt++;
  178.  
  179.     /* clear delayed expunges (standard procedure) */
  180.     libbase->ml_Lib.lib_Flags &= ~LIBF_DELEXP;
  181.  
  182. #ifndef ONE_GLOBAL_SECTION
  183.     /* Allocate new lib base */
  184.     newlib = AllocMem((long)(MYLIBRARYSIZE + 
  185.                              ((long)&RESLEN) + SIZEJMPTAB), 
  186.                              MEMF_PUBLIC|MEMF_CLEAR);
  187.  
  188.     if (newlib == NULL) goto error;
  189.         
  190.     /* copy over data */
  191.     memcpy(newlib, (char *)libbase - SIZEJMPTAB, 
  192.            (long)(MYLIBRARYSIZE + DATAWORDS*4 + SIZEJMPTAB));
  193.     
  194.     libbase = (struct MyLibrary *)(newlib+SIZEJMPTAB);
  195.     libbase->ml_relocs = NULL;
  196.     
  197.     /* perform relocs */       
  198.     ddata = (long *)((char *)libbase + MYLIBRARYSIZE); 
  199.     sdata = libbase->ml_origbase->ml_relocs;
  200.     if (sdata)
  201.     {
  202.        nrelocs = *sdata++;
  203.        while (nrelocs > 0)
  204.        {
  205.           reloc = (long *)((long)ddata + *sdata++);
  206.           *reloc += (long)ddata;
  207.           nrelocs--;
  208.        }
  209.     }
  210.  
  211.     /* now we need to flush the cache because we copied the jmp table */
  212.     if (SysBase->LibNode.lib_Version >= 36) 
  213.       CacheClearU();
  214.  
  215. #ifdef DEVICE
  216.     ior->io_Device = (struct Device *)libbase; /* local copy of libary base */
  217. #endif
  218.  
  219.     if (__libfpinit(libbase) || 
  220. #ifdef DEVICE
  221.         __UserDevInit(unit, ior, libbase) != 0
  222. #else
  223.         __UserLibInit(libbase) != 0
  224. #endif
  225.        )
  226.     {
  227.        __libfpterm(libbase);
  228.        FreeMem(newlib, (long)(MYLIBRARYSIZE + 
  229.                        ((long)&RESLEN) + SIZEJMPTAB));
  230. error:
  231.        origbase->ml_origbase->ml_Lib.lib_OpenCnt--;
  232.        return NULL; /* abort if user init failed */
  233.     }
  234.  
  235. #else
  236. #ifdef DEVICE
  237.     if (__UserDevInit(unit, ior, libbase) != 0)
  238.     {
  239.         libbase->ml_Lib.lib_OpenCnt--;
  240.         return NULL;
  241.     }    
  242. #endif
  243. #endif
  244.  
  245.     return ( (LONG) libbase );
  246. }
  247.  
  248. ULONG __asm _LibClose( 
  249. #ifdef DEVICE
  250.                        register __a1 struct IORequest *ior,
  251. #endif                       
  252.                        register __a6 struct MyLibrary *libbase )
  253. {
  254.     ULONG retval = 0;
  255.     
  256. #ifndef ONE_GLOBAL_SECTION
  257.     struct MyLibrary *origbase;
  258.  
  259.     if (libbase != libbase->ml_origbase)
  260.     {
  261. #ifdef DEVICE
  262.        __UserDevCleanup(ior, libbase);
  263. #else
  264.        __UserLibCleanup(libbase);
  265. #endif
  266.        __libfpterm(libbase);
  267.        origbase = libbase->ml_origbase;
  268.        FreeMem((char *)libbase-SIZEJMPTAB, 
  269.                (long)(MYLIBRARYSIZE + ((long)&RESLEN)+SIZEJMPTAB));
  270.        libbase = origbase;
  271.     }
  272. #else
  273. #ifdef DEVICE
  274.     __UserDevCleanup(ior, libbase);
  275. #endif
  276. #endif
  277.  
  278.     if (( --libbase->ml_Lib.lib_OpenCnt == 0 ) &&
  279.                         ( libbase->ml_Lib.lib_Flags & LIBF_DELEXP ))
  280.     {
  281.         /* no more people have me open,
  282.          * and I have a delayed expunge pending
  283.          */
  284.          retval = _LibExpunge( libbase ); /* return segment list        */
  285.     }
  286.  
  287.     return (retval);
  288. }
  289.  
  290. ULONG __asm _LibExpunge( register __a6 struct MyLibrary *libbase )
  291. {
  292.     ULONG seglist = 0;
  293.     LONG  libsize;
  294.  
  295. #ifndef ONE_GLOBAL_SECTION
  296.     libbase = libbase->ml_origbase;
  297. #endif
  298.  
  299.     libbase->ml_Lib.lib_Flags |= LIBF_DELEXP;
  300.     if ( libbase->ml_Lib.lib_OpenCnt == 0 )
  301.     {
  302.         /* really expunge: remove libbase and freemem        */
  303. #ifndef ONE_GLOBAL_SECTION
  304.         if (libbase->ml_relocs)
  305.            FreeMem(libbase->ml_relocs, (*libbase->ml_relocs * 4) + 4);
  306. #else
  307.         if (__UserLibCleanup(libbase) != 0) return NULL;
  308. #endif
  309.         seglist = libbase->ml_SegList;
  310.  
  311.         Remove( (struct Node *) libbase);
  312.  
  313.         libsize = libbase->ml_Lib.lib_NegSize + libbase->ml_Lib.lib_PosSize;
  314.         FreeMem( (char *) libbase - libbase->ml_Lib.lib_NegSize,(LONG) libsize );
  315.     }
  316.  
  317.     /* return NULL or real seglist                                */
  318.     return ( (ULONG) seglist );
  319. }
  320.